//! # 单个对象包装器
//!
//! 用于包装单个对象查询结果的结构体
//!
//! 该结构体实现了 [ResponseTrait] trait，提供统一的响应处理接口。
//! 数据部分使用 [Option]<T> 类型存储，当操作成功时包含数据，
//! 失败时为 [None]。

use serde::{Deserialize, Serialize};

use crate::wrapper::response_trait::ResponseTrait;
use crate::wrapper::response_wrapper::ResponseWrapper;

/// 单个对象包装结构体
///
/// 用于统一 API 单个对象响应格式，包含状态码、消息和单个数据对象
///
/// 参见: [ResponseTrait], [ResponseWrapper]
#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct SingleWrapper<T> {
    /// 基础响应包装器
    ///
    /// 类型: [ResponseWrapper]
    ///
    /// 包含响应的状态码和消息，用于表示操作结果
    base: ResponseWrapper,
    /// 数据对象
    ///
    /// 类型: [Option]<T> (泛型)
    ///
    /// 当操作成功时包含数据对象，失败时为 [None]
    data: Option<T>,
}

impl<T> SingleWrapper<T> {
    /// 创建一个新的 SingleWrapper，数据为空
    ///
    /// 创建一个默认成功的 SingleWrapper 实例，数据部分初始化为 [None]
    ///
    /// # 返回值
    ///
    /// [SingleWrapper]<T> - 新的SingleWrapper实例
    ///
    /// # 泛型参数
    ///
    /// * T - 数据对象的类型
    pub fn new() -> Self {
        Self { base: ResponseWrapper::success_default(), data: None }
    }

    /// 创建一个默认失败的 SingleWrapper，数据为空
    ///
    /// 创建一个默认失败状态的 SingleWrapper 实例，数据部分为 [None]
    ///
    /// # 返回值
    ///
    /// [SingleWrapper]<T> - 新的SingleWrapper实例（失败状态）
    ///
    /// # 泛型参数
    ///
    /// * T - 数据对象的类型
    pub fn fail_default() -> Self {
        Self { base: ResponseWrapper::fail_default(), data: None }
    }

    /// 创建一个默认未知错误的 SingleWrapper，数据为空
    ///
    /// 创建一个默认未知错误状态的 SingleWrapper 实例，数据部分为 [None]
    ///
    /// # 返回值
    ///
    /// [SingleWrapper]<T> - 新的SingleWrapper实例（未知错误状态）
    ///
    /// # 泛型参数
    ///
    /// * T - 数据对象的类型
    pub fn unknown_error_default() -> Self {
        Self {
            base: ResponseWrapper::unknown_error_default(),
            data: None,
        }
    }

    /// 设置为成功状态并附带数据
    ///
    /// 将当前实例设置为成功状态，并用指定的数据对象填充数据部分
    ///
    /// # 参数
    ///
    /// * `data` - 要包装的数据对象，类型: T
    ///
    /// # 泛型参数
    ///
    /// * T - 数据对象的类型
    pub fn set_success(&mut self, data: T) {
        self.base = ResponseWrapper::success_default();
        self.data = Some(data);
    }

    /// 设置为失败状态并附带消息
    ///
    /// 将当前实例设置为失败状态，并用指定的消息更新响应消息
    ///
    /// # 参数
    ///
    /// * `msg` - 失败消息，类型: impl [Into]<[String]>，可以接受 &str 或 String
    pub fn set_fail(&mut self, msg: impl Into<String>) {
        self.base.set_fail(msg);
        self.data = None;
    }

    /// 设置为未知错误状态并附带消息
    ///
    /// 将当前实例设置为未知错误状态，并用指定的消息更新响应消息
    ///
    /// # 参数
    ///
    /// * `msg` - 未知错误消息，类型: impl [Into]<[String]>，可以接受 &str 或 String
    pub fn set_unknown_error(&mut self, msg: impl Into<String>) {
        self.base.set_unknown_error(msg);
        self.data = None;
    }

    /// 获取基础响应包装器的引用
    ///
    /// # 返回值
    ///
    /// &[ResponseWrapper] - 基础响应包装器的引用
    pub fn get_base(&self) -> &ResponseWrapper {
        &self.base
    }

    /// 获取数据对象的引用
    ///
    /// # 返回值
    ///
    /// &[Option]<T> - 数据对象的引用（Option包装）
    ///
    /// # 泛型参数
    ///
    /// * T - 数据对象的类型
    pub fn get_data(&self) -> &Option<T> {
        &self.data
    }

    /// 对包装的数据执行类型转换操作
    ///
    /// 如果当前包装器处于成功状态，则使用提供的函数 [f] 将内部数据从类型 T 转换为类型 U，
    /// 并返回一个新的成功状态的 [SingleWrapper]<U> 实例。
    /// 如果当前包装器处于失败状态，则返回一个新的失败状态的 [SingleWrapper]<U> 实例，
    /// 保留原始的错误代码和消息。
    ///
    /// # 参数
    ///
    /// * `f` - 类型转换函数，接受 T 类型参数并返回 U 类型值
    ///
    /// # 泛型参数
    ///
    /// * T - 原始数据类型
    /// * U - 转换后的数据类型
    /// * F - 转换函数类型，必须实现 [FnOnce](T) -> U trait
    ///
    /// # 返回值
    ///
    /// [SingleWrapper]<U> - 转换后的新包装器实例
    ///
    /// # 示例
    ///
    /// ```
    /// use common_wrapper::SingleWrapper;
    /// use common_wrapper::ResponseTrait;
    ///
    /// let mut int_wrapper = SingleWrapper::new();
    /// int_wrapper.set_success(42);
    ///
    /// let string_wrapper = int_wrapper.map(|x| x.to_string());
    ///
    /// assert!(string_wrapper.is_success());
    /// assert_eq!(string_wrapper.get_data(), &Some("42".to_string()));
    /// ```
    pub fn map<U, F>(self, f: F) -> SingleWrapper<U>
    where
        F: FnOnce(T) -> U,
    {
        let mut new_wrapper = SingleWrapper::<U>::new();
        if self.is_success() {
            if let Some(data) = self.data {
                new_wrapper.set_success(f(data));
            } else {
                new_wrapper.data = None;
            }
        } else {
            new_wrapper.base = self.base;
            new_wrapper.data = None;
        }
        new_wrapper
    }
}

impl<T> Default for SingleWrapper<T> {
    fn default() -> Self {
        Self::new()
    }
}

/// 实现 ResponseTrait 以便统一处理响应包装
impl<T> ResponseTrait for SingleWrapper<T> {
    /// 获取响应码
    ///
    /// 从基础响应包装器中获取响应码
    ///
    /// # 返回值
    ///
    /// [i32] - 响应码
    fn get_code(&self) -> i32 {
        self.base.get_code()
    }

    /// 获取响应消息
    ///
    /// 从基础响应包装器中获取响应消息
    ///
    /// # 返回值
    ///
    /// &[str] - 响应消息的引用
    fn get_message(&self) -> &str {
        self.base.get_message()
    }

    /// 判断是否为成功响应
    ///
    /// 根据基础响应包装器判断是否为成功响应
    ///
    /// # 返回值
    ///
    /// [bool] - 如果响应成功返回true，否则返回false
    fn is_success(&self) -> bool {
        self.base.is_success()
    }

    /// 设置为失败响应，并自定义消息，数据清空
    ///
    /// # 参数
    ///
    /// * `msg` - 自定义的失败消息，类型: impl [Into]<[String]>
    fn set_fail(&mut self, msg: impl Into<String>) {
        self.base.set_fail(msg);
        self.data = None;
    }

    /// 设置为未知错误响应，并自定义消息，数据清空
    ///
    /// # 参数
    ///
    /// * `msg` - 自定义的未知错误消息，类型: impl [Into]<[String]>
    fn set_unknown_error(&mut self, msg: impl Into<String>) {
        self.base.set_unknown_error(msg);
        self.data = None;
    }
}
